<?php
/**
 * 制作:  叶风
 * Qq:    355007778
 * Email: ye.fn@163.com
 */
class files
{
	function charset_p($str)
	{
		if (YF_f::$config['charset_sys'])
			return mb_convert_encoding($str, YF_f::$config['charset'], YF_f::$config['charset_sys']);;
		return $str;
	}
	function charset_sys($str)
	{
		if (YF_f::$config['charset_sys'])
			return mb_convert_encoding($str, YF_f::$config['charset_sys'], YF_f::$config['charset']);
		return $str;
	}
    /**
     * 创建目录
     * @param string $dir
     * @return boolean
     */
    function c_dir($dir)
    {
        return is_dir($dir) ? true : (mkdir($dir, 0777, true) or YF_f::error($dir));
    }
    /**
     * 删除目录   
     * @param string $dir
     * @param boolean $delMy 删除自身
     * @param int $time  秒，之前的不删除
     * @return boolean
     */
    function del_dir($dir, $delMy=true, $time=0)
    {
        if (!is_dir($dir))
          return false;
        
        if ($time>0)
        	$t = strtotime("- $time seconds");
        else
            $t = 0;
		$b = true;
        foreach( glob($dir.'*', GLOB_MARK ) as $v)
         {
			if (is_dir($v))
             	$this->del_dir($v, true, $time);
        	else{
				if ($t &&  (filemtime($v) > $t) )
				 	continue;
                if (!unlink($v))
					$b = false; 
             }
         }
    	if ($delMy && !rmdir($dir))
        	$b = false;
        return $b;
    }
    /**
     * 复制目录
     * @param type $d
     * @param type $t
     * @return boolean
     */
    function copy_dir($d, $t)
    {
        if (realpath($d)==realpath($t))
            return true;

        if (is_dir($d))
          {
            is_dir($t) or $this->c_dir($t);
            foreach( glob($d.'*', GLOB_MARK) as $v)
              { 
                $b = is_dir($v) ? $this->copy_dir($v, $t.basename($v) . DIRECTORY_SEPARATOR) : copy($v, $t.basename($v));
                if (!$b)
                	return false;
              }
            return true;
          }
    }

    /**
     * 子目录
     * 
     */
    function dirList($dir)
    {
        if (!is_dir($dir) )
        	return array();
        	
    	$lists = array();
    	$dir =  realpath($dir) . DIRECTORY_SEPARATOR;
        $n = strlen($dir);
         
        foreach(glob($dir .'*', GLOB_MARK ) as $v)
        	if(is_dir($v))
        	 {
        	 	$lists[] = $this->charset_p(substr($v, $n, -1));
        	 }         
        return $lists;
    }
    
    /**
     * 效验合法的文件路径
     * @param string $root 根目录
     * @param type $path 相对路径
     * @return string|boolean  返回相对$root的文件路径
     */
    function ok_path($root, $path)
    {
    	is_dir($root) or $this->c_dir($root);
    	$root = realpath($root) . DIRECTORY_SEPARATOR ;
    	
		$path = $this->charset_sys($path);
		$path = realpath($root . $path);
		if (!is_file($path)) 
			$path .= DIRECTORY_SEPARATOR;
        
		if (strpos($path, $root)===0)
         	return substr($path, strlen($root));
		return false;
    }
    /**
     * 校验扩展名
     * @param type $f
     * @param type $arr
     * @return boolean
     */
    function has_ext($f, $arr)
    {
        is_array($arr) or $arr=  explode(',', $arr);
        
        $f = explode(".", $f);
    	return in_array(strtolower(array_pop($f)), $arr);
    }
    function get_ext($file)
    {
        $ext = explode('.', $file);
        return array_pop($ext);
    }
    function getList($dir, $pathPre='')
    {
        $res = array();
        if (!is_dir($dir))
            return $res;
        $dir =  realpath($dir) . DIRECTORY_SEPARATOR;
    	foreach(glob($dir .'*') as $v)
    	 {
    		$finfo = stat($v);
    		
    		$name = $this->charset_p($v);
            $_a =  explode(DIRECTORY_SEPARATOR, $name);
            $name = array_pop($_a);
    		//缩略图
    		if(is_dir($v))
    			$type = 'folder';
    		else{
    			$_a = explode('.',$name);
    			$type = strtolower(array_pop($_a));
    			if( in_array($type, array('gif','jpg','jpeg','png')))
    				$type = 'img';
    		  }
    	
    		$res[] = array('name'	=> $name,
    					'path'		=> $pathPre.$name,
    					'ctime' 	=> date('Y-m-d H:i:s', $finfo['ctime']),
    					'size'		=> $finfo['size'],
    					'type' 		=> $type
    					);
    	 }
    	return $res;
    }
    //
    function i_filename($dir, $fileName)
    {
        if (file_exists($dir . $fileName)) 
		 {
			$extP = strrpos($fileName, '.');
			$fileName_a = substr($fileName, 0, $extP);
			$fileName_b = substr($fileName, $extP);
			$count = 0;
			do{
                ++$count;
                $fileName = $fileName_a . '_' . $count . $fileName_b; //重新赋值
			}
			while (file_exists($dir . $fileName));
		 }
        return $fileName;
    }
    // 写文件
    function w_file($file, $str='')
    {
        if (file_exists($file)) 
            return file_put_contents($file, $str);
        
        $dir = dirname($file) ;
        $this->c_dir($dir);
        $b = file_put_contents($file, $str);
		chmod($file, 0777);
        return $b;
    }
    // 读文件
    function r_file($f)
    {
		set_time_limit(600);
		if (preg_match("/^http:|^https:/",$f))
			$content = YF_f::q_curl($f, null, 0, true);
		else
			$content = file_get_contents($f);
		return $content;
    }
    /**
     *  下载文件
     */
	function download($file, $obj=null)
	{
        if ($obj)
		 {
			if (is_string($obj))
				$downName = $obj;
			else
				extract($obj);
		 }
        if (!$downName)
         {
            $t = explode(DIRECTORY_SEPARATOR, realpath($file));
		 	$downName = $this->charset_p(end($t));
		 }
        if (!is_file($file))
		  {	
		  	if ($reError)
		  		return 404;
		  	header("HTTP/1.1 404 Not Found");
		  	die('404 Not Found');
		  }
          
		@set_time_limit(300);
	    $fileStat = stat($file); 
	    $lastModified = $fileStat['mtime']; 
	    $md5 = md5($fileStat['mtime'] .'='. $fileStat['ino'] .'='. $fileStat['size']); 
	    $etag = '"' . $md5 . '-' . crc32($md5) . '"'; 
	    header('Last-Modified: ' . gmdate("D, d M Y H:i:s", $lastModified) . ' GMT'); 
	    header("ETag: $etag"); 
        header('Pragma: cache'); 
	    header('Cache-Control: public, must-revalidate, max-age=0'); 
	    if (isset($_SERVER['HTTP_IF_NONE_MATCH']) &&  $_SERVER['HTTP_IF_NONE_MATCH'] == $etag) 
	      { 
	        header("HTTP/1.1 304 Not Modified"); 
	        die; 
	      }
          
	    //分块
        $fileSize = $fileStat['size']; 
	    if (isset($_SERVER['HTTP_RANGE']) && preg_match('/^bytes=(\d*)-(\d*)$/', $_SERVER['HTTP_RANGE'], $matches)) 
	      { 
            $startPos = $matches[1]; 
            $endPos = $matches[2]; 
  
            if ($startPos == '') 
              { 
                $startPos = $fileSize - $endPos; 
                $endPos = $fileSize - 1; 
              } 
            else if ($endPos == '') 
              { 
                $endPos = $fileSize - 1; 
              } 
  
            $startPos = $startPos < 0 ? 0 : $startPos; 
            $endPos = $endPos > $fileSize - 1 ? $fileSize - 1 : $endPos; 
  
            $contentLength = $endPos - $startPos + 1; 
  
            if ($contentLength < 0) 
          		die;

            header('HTTP/1.1 206 Partial Content'); 
	        header("Content-Range: bytes $startPos-$endPos/$fileSize"); 
	           
	      }
	   	else{
	   		$contentLength = $fileSize;  
	        $startPos = 0; 
	        $endPos = $contentLength - 1; 
	        header("HTTP/1.1 200 OK");
	   	 } 
	 
	    header('Accept-Ranges: bytes'); 
	    header('Content-Length: ' . $contentLength);
	    header('Content-type: application/octet-stream');
	   	header('Content-Disposition: attachment; filename="' . $downName. '"'); 
	    header("Content-Transfer-Encoding: binary"); 
	    // 读取
	    $bufferSize = 2048; 
	    $bytesSent = 0; 
	    $fp = fopen($file, "rb"); 
	    fseek($fp, $startPos); 
	    while ($bytesSent < $contentLength && !feof($fp) ) 
	      { 	 
	    	connection_status(); 
	        $readBufferSize = $contentLength - $bytesSent ;
	        if ($readBufferSize > $bufferSize )
	        	 $readBufferSize = $bufferSize; 
	        
	        echo fread($fp, $readBufferSize); 
	        
	       	ob_flush(); 
	  
	        $bytesSent += $readBufferSize; 
	      } 
	    fclose($fp);
		die;
	}
}
?>